<template>
  <div style="height: 100%" class="tree-file-outer">
    <div class="tree-bar">
      <div style="">本地文件系统</div>
      <div style="flex-grow: 1"></div>
      <div v-if="curNode && curNode.nodeType === 'folder'" class="top-btn">
        <Upload :before-upload="handleUpload" multiple action="">
          <Button size="small" type="primary" title="添加">上传</Button>
        </Upload>
      </div>
      <div v-if="curNode && curNode.nodeType === 'folder'">
        <Button size="small" type="default" @click="exportFolder" title="导出">导出</Button>
      </div>
      <div v-if="curNode && curNode.nodeType === 'file'">
        <Button size="small" type="default" @click="exportFile" title="导出">导出</Button>
      </div>
    </div>

    <base-tree
      v-model="treeData"
      @on-select-node="selectTreeNode"
      @on-insert-node="initNode"
      @on-update-node="changeName"
      @on-delete-node="deleteNode"
      style="height: calc(100% - 32px)"
      ref="baseTreeRef"
    ></base-tree>

    <get-name-dialog ref="dialogRef"></get-name-dialog>
  </div>
</template>

<script>
import { cloneDeep } from 'lodash';
import localforage from 'localforage';
import tarball from '../base/tarball';
import { checkAndLoadFolderList, initFileNode, initFolderNode } from '../base/mateLocalUtil';
import { rootDefault } from '../base/mateLocalConst';
import BaseTree from '../components/BaseTree.vue';
import GetNameDialog from './GetNameDialog.vue';

export default {
  components: { BaseTree, GetNameDialog },
  name: 'TreeFile',
  data() {
    return {
      treeData: cloneDeep(rootDefault),
      curNode: null,
    };
  },
  watch: {
    treeData: {
      deep: true,
      handler: function () {
        localforage.setItem('_folderList', this.treeData);
      },
    },
  },
  methods: {
    exportFile() {
      if (this.curNode.nodeType !== 'file') {
        return;
      }
      localforage.getItem(this.curNode.fileKey).then(fileObj => {
        let linkEle = document.createElement('a');
        linkEle.href = URL.createObjectURL(fileObj);
        linkEle.download = fileObj.name;
        document.body.appendChild(linkEle);
        linkEle.click();
        document.body.removeChild(linkEle);
      });
    },
    exportFolder() {
      if (this.curNode.nodeType !== 'folder') {
        return;
      }
      const fileInfoList = this.curNode.children.map(fileNode => {
        return localforage.getItem(fileNode.fileKey);
      });
      Promise.all(fileInfoList).then(fileList => {
        let tar = new tarball.TarWriter();
        fileList.forEach(contentObj => {
          tar.addFile(contentObj.name, contentObj);
        });
        tar.download(this.curNode.title + '.tar');
      });
    },
    handleUpload(curFile) {
      const fileNode = initFileNode(curFile, this.curNode.nodeId);
      localforage.setItem(fileNode.fileKey, curFile).then(() => {
        this.curNode.children.push(fileNode);
        if (!this.curNode.expand) {
          this.curNode.expand = true;
        }
      });
      // 终止上传请求动作
      return false;
    },

    initNode() {
      // curNode为root
      this.$refs.dialogRef.openDialog().then(retStr => {
        if (this.curNode) {
          this.curNode.children.push(initFolderNode(retStr));
        }
      });
    },
    changeName() {
      this.$refs.dialogRef.openDialog(this.curNode.title).then(retStr => {
        this.curNode.title = retStr;
        this.curNode.fileInfo.name = retStr;
      });
    },

    deleteNode() {
      if (!this.curNode) return;

      let parentNode;
      let actionList = [];
      if (this.curNode.nodeType === 'folder') {
        parentNode = this.treeData[0];
        actionList = this.curNode.children.map(item => {
          return localforage.removeItem(item.fileKey);
        });
      } else {
        parentNode = this.treeData[0].children.find(item => {
          return item.nodeId === this.curNode.parentId;
        });
        actionList.push(localforage.removeItem(this.curNode.fileKey));
      }

      // 缓存curNode的key
      const tmpId = this.curNode.nodeId;
      // 移除相关文件
      Promise.all(actionList).then(() => {
        // 移除选中节点
        parentNode.children = parentNode.children.filter(item => {
          return item.nodeId !== tmpId;
        });
      });

      // 选中新节点
      let newKey = this.treeData[0].nodeKey;
      if (parentNode.children.length > 0) {
        newKey = parentNode.children[0].nodeKey;
      }
      this.$refs.baseTreeRef.handleSelect(newKey);
    },

    selectTreeNode(curNode) {
      this.curNode = curNode;
      this.$emit('select-tree-node', this.curNode);
    },
  },
  mounted() {
    checkAndLoadFolderList().then(retObj => {
      this.treeData = retObj;
      this.curNode = this.treeData[0];
      this.selectTreeNode(this.curNode);
      setTimeout(() => {
        if (!this.treeData[0].selected) {
          this.$refs.baseTreeRef.handleSelect(0);
        }
      });
    });
  },
};
</script>

<style scoped>
.tree-bar {
  display: flex;
  height: 32px;
  line-height: 36px;
  background-color: #ffffff;
  padding: 0 16px;
}

.top-btn {
  /* width: 40px; */
  margin-right: 4px;
}
</style>
